from typing import Tuple, Callable

from apps.app_tx_meeting.managers import tx_meeting_configs
from apps.app_tx_meeting.builders import build_tx_meeting_client
from apps.app_tx_meeting.tx_clients import inputs


class MeetReservationHelper:
    @staticmethod
    def room_reserve_start_end(start_time: int, end_time: int) -> Tuple[int, int]:
        """
        通过用户的会议预定时间段，计算会议室资源预留的时间段
        """
        return MeetReservationHelper.room_reserve_before_after_time_adder()(start_time, end_time)

    @staticmethod
    def room_reserve_before_after_time_adder() -> Callable[[int, int], Tuple[int, int]]:
        """
        会议室预定前后多预留时间计算

        * 配置有误，默认前置按15分钟， 后置时间最小为0
        """
        advance_minutes = tx_meeting_configs.get(tx_meeting_configs.ConfigName.RESERVE_ROOM_ADVANCE_MINUTTES.value)
        advance_minutes = max(int(advance_minutes), 15)
        after_minutes = tx_meeting_configs.get(tx_meeting_configs.ConfigName.MEETING_AFTER_RESERVE_MINUTES.value)
        after_minutes = max(int(after_minutes), 0)

        def _adder(start_time: int, end_time: int) -> Tuple[int, int]:
            room_reserve_start = start_time - (60 * advance_minutes)
            room_reserve_end = end_time + (60 * after_minutes)
            return room_reserve_start, room_reserve_end

        return _adder

    @staticmethod
    def meeting_notice_time_advance_seconds(start_time: int) -> Tuple[int, int]:
        """
        通过用户的会议预定开始时间，计算默认会前通知发送时间

            * 配置有误，默认按30分钟
        """
        advance_minutes = tx_meeting_configs.get(tx_meeting_configs.ConfigName.DEFAULT_ADVANCE_NOATICE_MINUTES.value)
        advance_minutes = max(int(advance_minutes), 30)
        advance_seconds = 60 * advance_minutes

        notice_time = start_time - advance_seconds
        return notice_time, advance_seconds

    @staticmethod
    def tx_release_room_1(tx_meeting_userid: str, room_type: int) -> Tuple[bool, str]:
        """
        请求腾讯会议服务，为用户释放会议室资源-1

        :param tx_meeting_userid: 腾讯会议创建者id
        :param room_type: 会议室规格，单位方
        :return: (
            ok: bool,       # True: suceess; False: failed
            message: str    # 结果描述
        )
        """
        tx_cli = build_tx_meeting_client()

        # 查询用户已预留会议室信息
        r = tx_cli.list_reserve_meeting_room_users(
            params=inputs.ListReserveMeetingRoomUserInput(
                userid=tx_meeting_userid, search_types='1'
            )
        )
        if not r.ok:
           return False, str(r.error)

        if not r.data.meeting_room_users:
            return True, f'用户"{tx_meeting_userid}"之前预留{room_type}方会议室资源为0，未去实际请求释放资源'

        meeting_room_count = 0
        for mru in r.data.meeting_room_users:
            if mru.resource_type == room_type:
                meeting_room_count = mru.meeting_room_count
                break

        if meeting_room_count <= 0:
            return True, f'用户"{tx_meeting_userid}"之前预留{room_type}方会议室资源数为{meeting_room_count}，未去实际请求释放资源'

        # 释放资源，给用户预留会议室资源数 -1
        new_meeting_room_count = meeting_room_count - 1
        message = f'用户"{tx_meeting_userid}"之前预留{room_type}方会议室资源数为{meeting_room_count}，预留数成功更新为{new_meeting_room_count}'
        r = tx_cli.post_reserve_meeting_room_users(
            params=inputs.PostReserveMeetingRoomUserInput(
                resource_type=room_type,
                meeting_room_users=[
                    inputs.PostMeetingRoomUser(
                        userid=tx_meeting_userid, meeting_room_num=new_meeting_room_count
                    )
                ]
            )
        )
        if not r.ok:
            return False, str(r.error)

        return True, message

    @staticmethod
    def tx_reserve_room_1(tx_meeting_userid: str, room_type: int) -> Tuple[bool, str]:
        """
        请求腾讯会议服务，为用户预留会议室资源+1

        :param tx_meeting_userid: 腾讯会议创建者id
        :param room_type: 会议室规格，单位方
        :return: (
            ok: bool,       # True: suceess; False: failed
            message: str    # 结果描述
        )
        """
        tx_cli = build_tx_meeting_client()

        # 查询用户已预留会议室信息
        r = tx_cli.list_reserve_meeting_room_users(
            params=inputs.ListReserveMeetingRoomUserInput(
                userid=tx_meeting_userid, search_types='1'
            )
        )
        if not r.ok:
            return False, str(r.error)

        if r.data.meeting_room_users:
            meeting_room_count = 0
            for mru in r.data.meeting_room_users:
                if mru.resource_type == room_type:
                    meeting_room_count = mru.meeting_room_count
                    break

            new_meeting_room_count = max(meeting_room_count, 0) + 1
            message = f'用户"{tx_meeting_userid}"之前预留{room_type}方会议室资源数为{meeting_room_count}，预留数成功更新为{new_meeting_room_count}'
        else:
            meeting_room_count = 0
            new_meeting_room_count = meeting_room_count + 1
            message = f'用户"{tx_meeting_userid}"之前预留{room_type}方会议室资源数为0，预留数成功更新为{new_meeting_room_count}'

        # 给用户预留会议室资源数 +1
        r = tx_cli.post_reserve_meeting_room_users(
            params=inputs.PostReserveMeetingRoomUserInput(
                resource_type=room_type,
                meeting_room_users=[
                    inputs.PostMeetingRoomUser(
                        userid=tx_meeting_userid, meeting_room_num=new_meeting_room_count
                    )
                ]
            )
        )
        if not r.ok:
            return False, str(r.error)

        return True, message
